package virtualinit;

import virtualinit.util.CommonUtil;
import virtualinit.util.JdbcUtil;
import virtualinit.util.Log;
import virtualinit.util.TimeUtil;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class B2cInit extends AbstractInit {
    static Log log = Log.instance;

    public void doStart() throws Exception {
        init();
        task.init(this);
        b2cStart();
    }

    @Override
    public String getTaskName() {
        return "b2c同步任务";
    }

    Map<String, SqlHolder> sqlCache = new HashMap<>(10000);
    Map<String, String> generalMap = new HashMap<>(30000000); // 3000万


    /**
     * o2o 店仓id 一致
     * <p>
     * b2c 使用st_stock_1 作为数据源
     * depot_store_id(ds_id) b2c为仓库id o2o为门店id',
     * mode_type=1
     * store_status=1
     * b2c 虚拟库存初始化
     */
    private void b2cStart() throws Exception {
        log.info("\n\n----------------------------------");
        log.info("b2c 同步开始...");

        // 缓存 storeId和channel 的关系
        String sql = "select store_id,channel_code from ?.sc_channel_store_rel where is_deleted=0 and mode_type=1 and store_status=1"
                .replace("?", JdbcUtil.quoteIdentifier(scheduleDbName));
        Map<String, String> storeToChannel = JdbcUtil.executeToMap(scheduleConn, sql)
                .stream().collect(Collectors.toMap(e -> e.get("store_id").toString(), e -> e.get("channel_code").toString()));
        log.info("   缓存storageId to channelId，size：{}", storeToChannel.size());


        String now = TimeUtil.now();

        // 获取input b2c只有表1
        sql = CommonUtil.format("select store_id,sku_id from ?.st_stock_1  where is_deleted=0",
                JdbcUtil.quoteIdentifier(storageDbName)) + config.initVirtualStockConfig.getLimit();

        // 把所有的l1 l2 l3 都查出来
        List<Map<String, Object>> allL1l2l3 = JdbcUtil.executeToMap(scheduleConn, l1l2l3_no_arg.replace("?", JdbcUtil.quoteIdentifier(scheduleDbName)));
        List<Map<String, Object>> maps = JdbcUtil.executeToMap(scheduleConn, l1l2l3_with_dsid.replace("?", JdbcUtil.quoteIdentifier(scheduleDbName)));
        Map<String, List<Map<String, Object>>> ds_id_toL1l1l2 = maps.stream().collect(Collectors.groupingBy(e -> e.get("ds_id").toString()));

        long sourceCount = totalSourceSize;
        log.info("开始读取 st_stock_1 ");
        JdbcUtil.exeCursorMap(storageConn, sql, data -> {
            String depot_store_id = data.get("store_id").toString();
            Object sku_id = data.get("sku_id");
            totalSourceSize++;

            List<Map<String, Object>> mapList = ds_id_toL1l1l2.get(depot_store_id);
            if (mapList != null) {
                for (Map<String, Object> d : mapList) {
                    String storeId = (String) d.get("cs_id");
                    String channelCode = storeToChannel.get(storeId);
                    Object is_share = d.get("is_share");
                    Object virtual_depot_id = d.get("id");

                    SqlHolder sqlHolder = super.getSqlHolder(sqlCache, channelCode, storeId);
                    if (sqlHolder == null) {
                        continue;
                    }
                    totalTarget++;
                    //tenant_id,app_id,created_time,updated_time,
                    sqlHolder.addValue(1, 1, now, now,
                            // virtual_depot_id,channel_id,store_id,sku_id,sku_type,feature
                            virtual_depot_id, channelCode, storeId, sku_id, 1, is_share);
                    if (sqlHolder.count % config.batchSize == 0) {
                        // 移交task处理
                        super.addSql(sqlHolder);
                        sqlHolder.reset();
                    }
                }
            }

            // 一个sku只能跑一次 公共数据
            if (generalMap.containsKey(sku_id)) {
                return;
            }
            generalMap.put(sku_id.toString(), null);
            for (Map<String, Object> d : allL1l2l3) {
                String storeId = (String) d.get("cs_id");
                String channelCode = storeToChannel.get(storeId);
                Object is_share = d.get("is_share");
                Object virtual_depot_id = d.get("id");

                SqlHolder sqlHolder = super.getSqlHolder(sqlCache, channelCode, storeId);
                if (sqlHolder == null) {
                    continue;
                }
                totalTarget++;
                sqlHolder.addValue(1, 1, now, now,
                        virtual_depot_id, channelCode, storeId, sku_id, 1, is_share);

                if (sqlHolder.count % config.batchSize == 0) {
                    super.addSql(sqlHolder);
                    sqlHolder.reset();
                }
            }
        });


        log.info("读取 st_stock_1 共：{}条", totalSourceSize - sourceCount);
        for (SqlHolder sqlHolder : sqlCache.values()) {
            super.addSql(sqlHolder);
        }

        task.handleCompleted();
        log.info("b2c 同步结束 total:{}  数据源条数：{} 插入条数：{} 渠道统计：{}", totalTarget, totalSourceSize, task.getWatch().totalCount.get(), tbCounts);
        log.info("----------------------------------\n\n");
    }

    public static void main(String[] args) {
        System.out.println();
    }
    static String l1l2l3_with_dsid =
            "SELECT svd.id, if(svd.is_top=2,0,svd.is_share) as is_share, svdc.cs_id, svdd.ds_id \n" +
                    "FROM ?.sc_virtual_depot AS svd\n" +
                    "\tINNER JOIN ?.sc_virtual_depot_cs svdc ON svd.id = svdc.virtual_depot_id\n" +
                    "\tINNER JOIN ?.sc_virtual_depot_ds svdd ON svd.id = svdd.virtual_depot_id \n" +
                    "WHERE\n" +
                    "\tsvd.mode_type = 1  AND svd.LEVEL = 1 and svdd.ds_id is not null \n" +
                    "\t\n" +
                    "UNION ALL\n" +
                    "\n" +
                    "SELECT svd.id,if(svd.is_top=2,0,svd.is_share) as is_share,svsg.cs_id, svdd.ds_id \n" +
                    "FROM ?.sc_virtual_depot AS svd\n" +
                    "\tINNER JOIN ?.sc_virtual_shared_group svsg ON svd.id = svsg.virtual_depot_id\n" +
                    "\tINNER JOIN ?.sc_virtual_depot_ds svdd ON svd.id = svdd.virtual_depot_id \n" +
                    "WHERE\n" +
                    "\tsvd.mode_type = 1 AND svd.LEVEL = 1 and svdd.ds_id is not null";
    static String l1l2l3_no_arg = "SELECT svd.id,if(svd.is_top=2,0,svd.is_share) as is_share,svdc.cs_id \n" +
            "FROM ?.sc_virtual_depot AS svd\n" +
            "INNER JOIN ?.sc_virtual_depot_cs svdc ON svd.id = svdc.virtual_depot_id \n" +
            "WHERE svd.LEVEL = 2 AND svd.mode_type = 1 \n" +
            "\t\n" +
            "UNION ALL\n" +
            "\n" +
            "SELECT svd.id,if(svd.is_top=2,0,svd.is_share) as is_share,svsg.cs_id \n" +
            "FROM ?.sc_virtual_depot AS svd\n" +
            "INNER JOIN ?.sc_virtual_shared_group svsg ON svd.id = svsg.virtual_depot_id \n" +
            "WHERE svd.LEVEL = 2 AND svd.mode_type = 1 \n" +
            "\t\n" +
            "UNION ALL\n" +
            "\n" +
            "SELECT svd.id,if(svd.is_top=2,0,svd.is_share) as is_share,svdc.cs_id \n" +
            "FROM ?.sc_virtual_depot AS svd\n" +
            "INNER JOIN ?.sc_virtual_depot_cs svdc ON svd.id = svdc.virtual_depot_id \n" +
            "WHERE svd.LEVEL = 3 AND svd.mode_type = 1";

    @Override
    protected Serializable getTableRoute(String storeId) {
        return 1;
    }
}
